﻿using System;
using System.Reflection;

namespace NLite.Reflection
{
    /// <summary>
    /// 
    /// </summary>
    public static class CustomAttributeProviderExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="member"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static T GetAttribute<T>(this ICustomAttributeProvider member, bool inherit)
            where T : Attribute
        {
            T[] attributes = member.GetCustomAttributes(typeof(T), inherit) as T[];

            if ((attributes == null) || (attributes.Length == 0))
                return null;
            else
                return attributes[0];
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="member"></param>
        /// <param name="type"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static object GetAttribute(this ICustomAttributeProvider member, Type type, bool inherit)
        {
            object[] attributes = member.GetCustomAttributes(type, inherit);

            if ((attributes == null) || (attributes.Length == 0))
                return null;
            else
                return attributes[0];
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="member"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static T[] GetAttributes<T>(this ICustomAttributeProvider member, bool inherit)
            where T : Attribute
        {
            return member.GetCustomAttributes(typeof(T), inherit) as T[];
        }
       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="member"></param>
        /// <param name="type"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static object[] GetAttributes(this ICustomAttributeProvider member, Type type, bool inherit)
        {
            return member.GetCustomAttributes(type, inherit);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="member"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static bool HasAttribute<T>(this ICustomAttributeProvider member, bool inherit)
            where T : Attribute
        {
            return member.IsDefined(typeof(T), inherit);
        }
       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="member"></param>
        /// <param name="type"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static bool HasAttribute(this ICustomAttributeProvider member, Type type, bool inherit)
        {
            return member.IsDefined(type, inherit);
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="member"></param>
        /// <param name="attributeToMatch"></param>
        /// <param name="inherit"></param>
        /// <returns></returns>
        public static bool HasMatchingAttribute<T>(this ICustomAttributeProvider member, T attributeToMatch, bool inherit)
            where T : Attribute
        {
            T[] attributes = member.GetAttributes<T>(inherit);

            if ((attributes == null) || (attributes.Length == 0))
                return false;

            foreach (T attribute in attributes)
            {
                if (attribute.Match(attributeToMatch))
                    return true;
            }

            return false;
        }
    }
}
